<?php

namespace app\api\controller\v2;

use think\Db;
use think\Request;
use think\Validate;
use GatewayClient\Gateway;
use app\api\controller\Common;
use app\api\model\Blacklist;
use app\api\model\VolleyDesc as Balance;
use app\api\model\ConfigSystem;
use app\api\model\Privatechat;
use app\api\model\User;

class Demand extends Common {
    /**
     * @var mixed
     */
    public $params = null;
    /**
     * @param Request $request
     */
    public function __construct(Request $request = null) {
        parent::__construct($request);
        $this->params = getRsaPostParamArr2();
    }

    public function publish()
    {
        $post['type'] = $this->params['type']??0;
        $post['price'] = $this->params['price']??0;
        $post['method'] = $this->params['method']??1;
        $post['city'] = $this->params['city']??'';
        $post['title'] = $this->params['title']??'';
        $post['content'] = $this->params['content']??'';
        $post['latitude'] = $this->params['latitude']??0;
        $post['longitude'] = $this->params['longitude']??0;
        $post['address'] = $this->params['address']??'';
        $post['imgs'] = input('imgs','');

        $post['state'] = 1;
        $post['user_id'] = $this->member['id'];
        $post['create_time'] = time();

        $validate = new Validate([
            ['type', 'require|in:0,1', '类型错误|类型错误'],
            ['price', 'require|between:50,10000', '价格不能为空|价格在50-10000之间'],
            ['method', 'require|in:1,2,3,4', '免费方式错误|免费方式错误'],
            ['title', 'require|length:4,20', '标题不能为空|标题名称在4-20字符之间'],
            ['content', 'require|length:10,100', '需求内容不能为空|需求内容名称在10-100字符之间'],
            // ['pay_method', 'require|in:1,2,3', '支付方式错误|支付方式错误'],
        ]);

        if (!$validate->check($post)) {
            return $this->miss($validate->getError());
        }

        if ($post['type'] == 1 && !$post['address']) return $this->miss('请选择地址');

        $cachekey = md5(serialize($post));
        if (cache($cachekey)) {
            return $this->pass('重复提交,请稍后重试');
        }
        cache($cachekey, $cachekey, 3);

        $post['order_sn'] = uniqid('dem');
        $config = ConfigSystem::index('fencheng','demand_fencheng');
        $post['settlement_price'] = number_format($post['price'] * $config['demand_fencheng'], 2, '.', '');

        $order_id = Db::name('user_demand')->insertGetId($post);

        if ($order_id) {
            return $this->pass('创建订单成功','msg',['order_sn'=>$post['order_sn']]);
        }
        return $this->miss('创建订单失败,请稍后重试');
    }

    public function pay()
    {
        $post['order_sn'] = $this->params['order_sn']??'dem668c943474024';
        $post['pay_method'] = $this->params['pay_method']??1;
        $validate = new Validate([
            ['order_sn', 'require', '订单号不能为空'],
            ['pay_method', 'require|in:1,2,3', '支付方式错误|支付方式错误'],
        ]);

        if (!$validate->check($post)) {
            return $this->miss($validate->getError());
        }

        $order = Db::name('user_demand')->where(['order_sn'=>$post['order_sn']])->find();
        if ($order['state'] != 1) return $this->miss('操作失败');
        if ($order['pay_state'] != 0) return $this->miss('订单已失效');
        $action = '';
        switch (intval($post['pay_method'])) {
            case 1:
                $timenow       = time();
                $priceToVolley = $order['price'] * 5;
                if ($priceToVolley > $this->member['volley']) {
                    return $this->miss('您的金币不足,所需金币:' . $priceToVolley);
                }
                try {
                    $res = Balance::index($this->member['id'], $priceToVolley, '发布需求订单 no.' . $order['order_sn']);
                    if ($res) {
                        Db::name('user_demand')->where(['id' => $order['id']])->update(['pay_state' => 1, 'pay_method' => 1, 'pay_time' => $timenow]);
                    }
                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                    return $this->miss('支付失败请重试');
                }

                return $this->pass('支付成功');
                break;
            case 2:
                $action = 'api/Alipay/tradeAppPay';
                break;
            case 3:
                $action = 'api/Wechat2/app';
                break;
            
            default:
                return $this->miss('支付方式错误');
                break;
        }
        return action($action, ['order_sn' => $order['order_sn'], 'total_amount' => $order['price']]);
    }

    public function mylist()
    {
        $page = $this->params['page'] ?? 1;
        $pagesize = $this->params['pagesize'] ?? 20;
        $pagesize = $pagesize > 20 || $pagesize <= 0 ? 20 : $pagesize;

        $where = ['user_id'=>$this->member['id']];

        $data = Db::name('user_demand')
            ->where($where)
            ->field('id,type,order_sn,status,state,pay_state,another_id,title,price,imgs,reason,create_time')
            ->page($page)
            ->limit($pagesize)
            ->order('id desc')
            ->select();

        $status = ['审核未通过','待审核','审核通过'];
        $state = ['退回','下架','上架','进行中','应征方已完成','订单完成'];
        $pay_state = ['订单已失效','待支付','已支付'];
        foreach ($data as &$value) {
            $value['create_time'] = date('Y-m-d H:i', $value['create_time']);
            if ($value['imgs']) {
                $value['imgs'] = explode(',', $value['imgs']);
            } else {
                $value['imgs'] = [];
            }
            $value['status_text'] = $status[$value['status']+1];
            $value['state_text'] = $state[$value['state']+1];
            $value['pay_state_text'] = $pay_state[$value['pay_state']+1];
        }
        return $this->pass($data);
    }

    public function all_list()
    {
        $type = $this->params['type'] ?? 0;
        $page = $this->params['page'] ?? 1;
        $pagesize = $this->params['pagesize'] ?? 20;
        $pagesize = $pagesize > 20 || $pagesize <= 0 ? 20 : $pagesize;

        $blacklist = Blacklist::lists($this->member['id'], true, false);
        $where = [
            'a.user_id'=>['not in', $blacklist],
            'a.type'=>$type,
            'a.status'=>1,
            'a.state'=>1,
            'a.pay_state'=>1,
            'u.delete_time'=>0,
            'u.is_banned'=>0,
            'u.reg'=>1
        ];

        $data = Db::name('user_demand')
            ->alias('a')
            ->join('user u', 'a.user_id=u.id')
            ->where($where)
            ->field('a.id,a.user_id,a.title,a.settlement_price price,a.imgs,a.create_time, u.name,u.head_portrait')
            ->page($page)
            ->limit($pagesize)
            ->order('a.audit_time desc, a.id desc')
            ->select();

        $channelProfiles = Db::name('user_channel_profile')->alias('p')->join('user_repeat_check c', 'c.user_id=p.user_id and c.sys_channel=p.sys_channel')->where(['p.user_id'=>['in', array_column($data, 'user_id')]])->column('p.*', 'p.user_id');

        foreach ($data as &$value) {
            if (isset($channelProfiles[$value['user_id']])) {
                $value['head_portrait'] = $channelProfiles[$value['user_id']]['head_portrait'];
                $value['name'] = $channelProfiles[$value['user_id']]['name'];
            }
            $value['create_time'] = date('Y-m-d H:i', $value['create_time']);
            if ($value['imgs']) {
                $value['imgs'] = explode(',', $value['imgs']);
            } else {
                $value['imgs'] = [];
            }
        }
        return $this->pass($data);
    }

    public function info()
    {
        $id = $this->params['id'] ?? 1;
        $data = Db::name('user_demand')->find($id);

        if (!$data) return $this->miss('数据异常10001');

        if ($data['user_id'] == $this->member['id']) {
            $data['pay_time'] = date('Y-m-d H:i', $data['pay_time']);
            if ($data['another_id']) {
                $data['another_info'] = _user_cache($data['another_id']);
            }
            unset($data['settlement_price'],
                $data['audit_time'],
                $data['update_time']);
        } else {
            if ($data['status']!=1) return $this->miss('数据异常10002');
            if ($data['pay_state']!=1) return $this->miss('数据异常10003');
            if ($data['pay_state']<1) return $this->miss('数据异常10004');
            if ($data['state'] > 1 && $data['another_id']!=$this->member['id']) return $this->miss('数据异常10005');
            $data['price'] = $data['settlement_price'];

            unset($data['settlement_price'],
                $data['audit_time'],
                $data['pay_time'],
                $data['pay_method'],
                $data['pay_state'],
                $data['status'],
                $data['order_sn'],
                $data['reason'],
                $data['update_time']);
        }

        $enrollUids = Db::name('user_demand_enroll')->where([
            'demand_id' =>  $id
        ])->column('user_id');

        $data['is_enroll'] = in_array($this->member['id'], $enrollUids);
        $data['enroll_count'] = sizeof($enrollUids);

        if ($data['imgs']) {
            $data['imgs'] = explode(',', $data['imgs']);
        } else {
            $data['imgs'] = [];
        }

        $data['create_time'] = date('Y-m-d H:i', $data['create_time']);
        $data['sub_time'] = $data['sub_time']?date('Y-m-d H:i', $data['sub_time']):0;

        $data['user'] = _user_cache($data['user_id']);

        return $this->pass($data);
    }

    public function enroll()
    {

        $cachekey = 'demandEnroll'.$this->member['id'];
        if (cache($cachekey)) return '';
        cache($cachekey, 1, 5);

        $id = $this->params['id'] ?? 6;
        $data = Db::name('user_demand')->find($id);
        if (!$data) return $this->miss('数据异常10001');
        if ($data['user_id'] == $this->member['id']) return $this->miss('数据异常10002');
        if ($data['pay_state'] != 1) return $this->miss('数据异常10003');
        if ($data['status'] != 1) return $this->miss('数据异常10004');
        if ($data['state'] != 1) return $this->miss('数据异常10005');
        if ($data['another_id'] != 0) return $this->miss('数据异常10006');

        $where = [
            'user_id'   =>  $this->member['id'],
            'demand_id' =>  $id
        ];

        $has = Db::name('user_demand_enroll')->where($where)->find();
        if ($has) return $this->miss('已应征,等待需求方确认');

        $where['create_time'] = time();

        $res = Db::name('user_demand_enroll')->insertGetId($where);

        return $res ? $this->pass('已应征,等待需求方确认') : $this->miss('应征失败,请稍后重试');
    }

    public function myenroll()
    {
        $type = $this->params['type'] ?? 0;
        $page = $this->params['page'] ?? 1;
        $pagesize = $this->params['pagesize'] ?? 20;
        $pagesize = $pagesize > 20 || $pagesize <= 0 ? 20 : $pagesize;

        $where = [
            'e.user_id'=>$this->member['id'],
            'a.type'=>$type,
            'a.status'=>1,
            'a.state'=>1,
            'a.pay_state'=>1,
            'u.delete_time'=>0,
            'u.is_banned'=>0,
            'u.reg'=>1
        ];

        $data = Db::name('user_demand_enroll')
            ->alias('e')
            ->join('user_demand a', 'a.id=e.demand_id')
            ->join('user u', 'a.user_id=u.id')
            ->where($where)
            ->field('a.id,a.user_id,a.title,a.settlement_price price,a.imgs,a.create_time, u.name,u.head_portrait,e.create_time enroll_time, e.status')
            ->page($page)
            ->limit($pagesize)
            ->order('e.id desc')
            ->select();

        $config = ConfigSystem::index('fencheng','demand_fencheng');


        $channelProfiles = Db::name('user_channel_profile')->alias('p')->join('user_repeat_check c', 'c.user_id=p.user_id and c.sys_channel=p.sys_channel')->where(['p.user_id'=>['in', array_column($data, 'user_id')]])->column('p.*', 'p.user_id');

        foreach ($data as &$value) {
            if (isset($channelProfiles[$value['user_id']])) {
                $value['head_portrait'] = $channelProfiles[$value['user_id']]['head_portrait'];
                $value['name'] = $channelProfiles[$value['user_id']]['name'];
            }
            $value['create_time'] = date('Y-m-d H:i', $value['create_time']);
            $value['enroll_time'] = date('Y-m-d H:i', $value['enroll_time']);
            if ($value['imgs']) {
                $value['imgs'] = explode(',', $value['imgs']);
            } else {
                $value['imgs'] = [];
            }
        }
        return $this->pass($data);
    }

    public function enroll_user()
    {
        $id = $this->params['id'] ?? 6;
        $page = $this->params['page'] ?? 1;
        $pagesize = $this->params['pagesize'] ?? 20;
        $pagesize = $pagesize > 20 || $pagesize <= 0 ? 20 : $pagesize;

        $data = Db::name('user_demand_enroll')
            ->alias('e')
            ->join('user u', 'u.id=e.user_id')
            ->where(['e.demand_id'=>$id])
            ->field('u.id,u.name,u.head_portrait,u.self_slogan,e.create_time,e.status')
            ->page($page)
            ->limit($pagesize)
            ->select();

        $channelProfiles = Db::name('user_channel_profile')->alias('p')->join('user_repeat_check c', 'c.user_id=p.user_id and c.sys_channel=p.sys_channel')->where(['p.user_id'=>['in', array_column($data, 'id')]])->column('p.*', 'p.user_id');

        foreach ($data as &$value) {
            if (isset($channelProfiles[$value['id']])) {
                $value['head_portrait'] = $channelProfiles[$value['id']]['head_portrait'];
                $value['name'] = $channelProfiles[$value['id']]['name'];
            }
            $value['create_time'] = date('Y-m-d H:i', $value['create_time']);
        }

        return $this->pass($data);
    }

    public function select_user()
    {
        $id = $this->params['id'] ?? 6;
        $touid = $this->params['touid'] ?? 12;

        $info = Db::name('user_demand')->where(['id'=>$id, 'user_id'=>$this->member['id'],'status'=>1,'state'=>1,'pay_state'=>1,'another_id'=>0])->find();
        if (!$info) return $this->miss('操作失败10001');

        $enroll = Db::name('user_demand_enroll')->where(['user_id'=>$touid, 'demand_id'=>$id])->find();
        if (!$enroll) return $this->miss('操作失败10002');
        if ($enroll['status']!=0) return $this->miss('操作失败10003');

        $timenow = time();
        Db::name('user_demand')->where(['id'=>$id])->update(['sub_time'=>$timenow, 'state'=>2, 'another_id'=>$touid]);
        $res = Db::name('user_demand_enroll')->where(['id'=>$enroll['id']])->update(['status'=>1,'sub_time'=>$timenow]);

        Db::name('privatechat_free')->insert([
            'user_id'     => $info['user_id'] > $touid ? $touid : $info['user_id'],
            'another_id'  => $info['user_id'] > $touid ? $info['user_id'] : $touid,
            'server'      => $touid,
            'order_sn'    => $info['order_sn'],
            'create_time' => $timenow,
            'start_time'  => 0,
            'end_time'    => 0,
            'method'      => $info['method'],
        ]);
        Privatechat::tip($info['user_id'], $touid, '你的应征被需求主选中了，请及时沟通并完成需求。', json_encode(['type'=>2,'demand_id'=>$id,'title'=>$info['title']], JSON_UNESCAPED_UNICODE), 1, -3);

        return $res ? $this->pass('选择成功') : $this->miss('选择失败');
    }

    public function finish()
    {
        $cachekey = 'demandFinish'.$this->member['id'];
        if (cache($cachekey)) return '';
        cache($cachekey, 1, 5);

        $id = $this->params['id'] ?? 6;
        $data = Db::name('user_demand')->where(['id'=>$id, 'user_id|another_id'=>$this->member['id'], 'state'=>['in', [2,3]]])->find();
        if (!$data) return $this->miss('数据异常10001');

        if ($data['user_id'] == $this->member['id']) {
            return $this->ourFinish($data);
        } else {
            $longitude = $this->member['longitude'];
            $latitude  = $this->member['latitude'];
            if ($data['longitude'] && $data['latitude']) {
                if (!$longitude || !$latitude) {
                    return $this->miss('位置未获取成功');
                }
                $distance = _distance($longitude, $latitude, $data['longitude'], $data['latitude'], 0);
                if ($distance > 100) {
                    return $this->miss('当前位置距离服务地点较远');
                }
            } else {
                $privatechat_free = Db::name('privatechat_free')->where(['order_sn' => $data['order_sn']])->find();
                $lianmaiMinute = $privatechat_free['audio_second'] + $privatechat_free['video_second'] > 0 ? ceil(($privatechat_free['audio_second'] + $privatechat_free['video_second']) / 60) : 0;
                if ($lianmaiMinute == 0) {
                    if ($privatechat_free['seller_msg'] < 200) {
                        return $this->miss('系统检测需求未完成，不可结束需求');
                    }
                } elseif ($lianmaiMinute <= 10) {
                    if ($privatechat_free['seller_msg'] < 150) {
                        return $this->miss('系统检测需求未完成，不可结束需求');
                    }
                } elseif ($lianmaiMinute <= 20) {
                    if ($privatechat_free['seller_msg'] < 100) {
                        return $this->miss('系统检测需求未完成，不可结束需求');
                    }
                } elseif ($lianmaiMinute <= 30) {
                    if ($privatechat_free['seller_msg'] < 50) {
                        return $this->miss('系统检测需求未完成，不可结束需求');
                    }
                } elseif ($lianmaiMinute <= 35) {
                    if ($privatechat_free['seller_msg'] < 0) {
                        return $this->miss('系统检测需求未完成，不可结束需求');
                    }
                } elseif ($lianmaiMinute > 35) {

                }
            }
            return $this->toFinish($data);
        }
    }

    private function ourFinish($data)
    {
        if (!in_array($data['state'], [2,3])) return $this->miss('操作异常10001');
        $res = false;
        Db::startTrans();
        $timenow = time();
        try {
            Db::name('user_demand')->where(['id'=>$data['id']])->update(['state'=>4, 'finish_time'=>$timenow]);
            $balance            = Db::name('user')->master()->where(['id' => $data['another_id']])->value('score');
            $money              = $data['settlement_price'] * getenv('APP_RATE');
            $current_balance    = $balance + $money;
            Db::name('user')->where(['id' => $data['another_id']])->setInc('score', $money);
            Db::name('yaoqing_records')->insert([
                'uid'      => $data['another_id'],
                'touid'    => $data['user_id'],
                'content'  => '需求订单完成结算',
                'money'    => $money,
                'type'     => 1,
                'data'     => 0,
                'order_id' => $data['order_sn'],
                'balance'  => $current_balance,
                'time'     => $timenow,
            ]);
            $chat_free_update = ['end_time' => $timenow];
            $chat_free_update['confirm'] = 4;
            Db::name('privatechat_free')->where(['order_sn' => $data['order_sn']])->update($chat_free_update);
            User::fencheng($data['another_id'], 0, $money, 'service', '需求订单完成');

            $res = true;
            Db::commit();
        } catch (\Exception $e) {
            $res = false;
            Db::rollback();
        }

        if ($res) {
            Gateway::sendToUid(getenv('SOCKET_PREFIX') . $data['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $data['another_id']]));
            Gateway::sendToUid(getenv('SOCKET_PREFIX') . $data['another_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $data['user_id']]));
            // Gateway::sendToUid(getenv('SOCKET_PREFIX') . $data['another_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/order/orderCount']));
            Privatechat::tip($data['user_id'], $data['another_id'], '本次需求已确认完成', json_encode(['type'=>2, 'demand_id'=>$data['id'], 'title'=>$data['title']], JSON_UNESCAPED_UNICODE), 0, -3);
            return $this->pass('操作成功');
        }

        return $this->miss('操作失败,请稍后重试');
    }

    private function toFinish($data)
    {
        if ($data['state'] != 2) return $this->miss('操作异常10001');
        $res = false;
        Db::startTrans();
        try {
            Db::name('user_demand')->where(['id'=>$data['id']])->update(['state'=>3]);
            Db::name('user_demand_enroll')->where(['user_id'=>$this->member['id'], 'demand_id'=>$data['id']])->update(['finish_time'=>time()]);
            $res = true;
            Db::commit();
        } catch (\Exception $e) {
            $res = false;
            Db::rollback();
        }

        if ($res) {
            Gateway::sendToUid(getenv('SOCKET_PREFIX') . $data['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $data['another_id']]));
            Gateway::sendToUid(getenv('SOCKET_PREFIX') . $data['another_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $data['user_id']]));
            // Gateway::sendToUid(getenv('SOCKET_PREFIX') . $data['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/order/orderCount']));
            Privatechat::tip($data['another_id'], $data['user_id'], '我已完成您的需求，请尽快确认（24小时后将自动确认）', json_encode(['type'=>2, 'demand_id'=>$data['id'], 'title'=>$data['title']], JSON_UNESCAPED_UNICODE), 0, -3);
            return $this->pass('操作成功');
        }

        return $this->miss('操作失败,请稍后重试');
    }
}